package base.loader
{
	import flash.events.EventDispatcher;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	import base.loader.ModuleLoader;
	
	/**
	 *加载工厂类 
	 */	
	public class LoaderFactory extends EventDispatcher
	{
		private var _loaders:Dictionary;
		private var _loaderIds:int=1;
		private var _loaderContext:LoaderContext;
		private var _loaderVersion:int;
		
		public function LoaderFactory()
		{
		}
		
		private static var _instance:LoaderFactory;
		public static function get Instance():LoaderFactory
		{
			if(_instance == null)
			{
				_instance = new LoaderFactory();
			}
			return _instance;
		}
		
		/**
		 *加载工厂类注册 
		 */
		public function register(loaderContext:LoaderContext, loaderVersion:int):void
		{
			_loaderContext=loaderContext;
			_loaderVersion=loaderVersion;
			LoaderBase.loaderContext=loaderContext;
			LoaderShared.Instance.register();
			_loaders = new Dictionary(true);
		}
		
		/**
		 * 创建Loader 
		 * @param loaderType Loader类型
		 * @param url 加载地址
		 * @param loaderFlagType Loader分类类别，用来区别当前加载所属，比如标识当前加载是属于加载技能相关资源的
		 * @param isMemory 是否加载到内存
		 * @param isSharedCache 是否加载到本地缓存，下次上线时可从本地缓存中读取
		 * @param repeat 重试次数
		 * @param urlVariables urlloader时的参数
		 * @param requestMethod urlloader时的URLRequestMethod方式
		 * @param level 加载优先级,按升序方式,0为最高优先级
		 * @return 
		 * 
		 */		
		public function createLoader(loaderType:String, url:String, loaderFlagType:String=LoaderFlagType.COMMON, isMemory:Boolean=true, isSharedCache:Boolean=true, repeat:int=3, urlVariables:URLVariables=null, requestMethod:String=URLRequestMethod.GET, level:int=99999):*
		{
			var baseLoader:BaseLoader=null;
//			if(isMemory)
//			{
//				switch(loaderType)
//				{
//					case LoaderType.LOADER:
//						baseLoader=loaders[url] as LoaderBase;
//						break;
//					case LoaderType.URLLOADER:
//						baseLoader=loaders[url] as URLLoaderBase;
//						break;
//					case LoaderType.MODULE_LOADER:
//						baseLoader=loaders[url] as ModuleLoader;
//						break;
//					case LoaderType.IMAGE_LOADER:
//						baseLoader=loaders[url] as ImageLoader;
//						break;
//				}
//			}
			
			if(!baseLoader)
			{
				switch(loaderType)
				{
					case LoaderType.LOADER:
						baseLoader=new LoaderBase(loaderFlagType, getLoaderID, url, isSharedCache, repeat, _loaderVersion, level);
						break;
					case LoaderType.URLLOADER:
						baseLoader=new URLLoaderBase(loaderFlagType, getLoaderID, url, isSharedCache, repeat, urlVariables, requestMethod, _loaderVersion, level);
						break;
					case LoaderType.MODULE_LOADER:
						baseLoader=new ModuleLoader(loaderFlagType, getLoaderID, url, isSharedCache, repeat, _loaderVersion, level);
						break;
					case LoaderType.IMAGE_LOADER:
						baseLoader=new ImageLoader(loaderFlagType, getLoaderID, url, isSharedCache, repeat, _loaderVersion, level);
						break;
				}
//				if(isMemory) _loaders[url]=baseLoader;
			}
//			else
//			{
//				if(baseLoader)baseLoader=baseLoader.clone();
//			}
			return baseLoader;
		}
		
		private var _allLoader:Array=[];
		private var _allLoading:Array=[];
		public function executeLoader(baseLoader:BaseLoader):void
		{
			_allLoader.push(baseLoader);
			if(_allLoading.indexOf(baseLoader)!=-1)_allLoading.splice(_allLoading.indexOf(baseLoader), 1);
			executeLoaderGo();
		}
		
		private function __onBaseLoaderComplete(evt:LoaderEvent):void
		{
			var baseLoader:BaseLoader=evt.currentTarget as BaseLoader;
			if(_allLoading.indexOf(baseLoader)!=-1)_allLoading.splice(_allLoading.indexOf(baseLoader), 1);
			baseLoader.removeEventListener(LoaderEvent.COMPLETE, __onBaseLoaderComplete);
			baseLoader=null;
			executeLoaderGo();
		}
		
		private function executeLoaderGo():void
		{
			_allLoader.sortOn("level", Array.NUMERIC);
			while(_allLoader.length>0 && _allLoading.length<5)
			{
				var baseLoader:BaseLoader=_allLoader.shift();
				if(!baseLoader.isDispose)
				{
					if(_allLoading.indexOf(baseLoader)==-1)_allLoading.push(baseLoader);
					baseLoader.addEventListener(LoaderEvent.COMPLETE, __onBaseLoaderComplete);
					baseLoader.executeGo();
				}
			}
		}
		
		public function delExecuteLoader(baseLoader:BaseLoader):void
		{
			baseLoader.removeEventListener(LoaderEvent.COMPLETE, __onBaseLoaderComplete);
			if(_allLoading.indexOf(baseLoader)!=-1)_allLoading.splice(_allLoading.indexOf(baseLoader), 1);
			if(_allLoader.indexOf(baseLoader)!=-1)_allLoader.splice(_allLoader.indexOf(baseLoader), 1);
			baseLoader=null;
		}
		
		public function addLoad(url:String):void
		{
			_loaders[url]=true;
		}
		
		/**
		 *是否已经加载过指定了的load 
		 * @param url
		 * @return 
		 * 
		 */		
		public function hasExistLoad(url:String):Boolean
		{
			if(_loaders[url]!=null)
			{
				return _loaders[url];
			}
			return false;
		}
		
		private function get getLoaderID():int
		{
			return _loaderIds+=1;
		}

		public function get loaderVersion():int
		{
			return _loaderVersion;
		}

	}
}